package com.siao.mvc.managers
{
	import com.siao.data.ArrayList;
	import com.siao.data.HashMap;
	import com.siao.errors.SingletonError;
	import com.siao.mvc.Model;
	import com.siao.mvc.core.IContext;
	
	/**
	 * 模型管理器
	 * @author SiaoLeon
	 */
	public class ModelManager
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		private static var _instance:ModelManager;
		
		/**
		 * 获取单例对象
		 */
		public static function get instance():ModelManager
		{
			if (_instance == null)
			{
				_instance = new ModelManager();
			}
			return _instance;
		}
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		private var models:HashMap;
		
		private var contexts:HashMap;
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数，单例模式
		 */
		public function ModelManager()
		{
			if (_instance != null)
			{
				throw new SingletonError(this);
			}
			_instance = this;
			
			this.init();
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		/**
		 * 添加模型
		 * @param model 模型类，需继承 Model 类
		 * @throws TypeError
		 */
		public function add(model:Class):void
		{
			if (!this.models.containsKey(model))
			{
				var instance:* = new model();
				
				if (!(instance is Model))
				{
					throw new TypeError(model + "不是继承 Model 类的有效对象");
				}
				
				this.models.put(model, instance);
				(instance as Model).onAdd();
			}
		}
		
		/**
		 * 移除模型
		 * @param  model 模型类，需继承 Model 类
		 */
		public function remove(model:Class):void
		{
			if (this.models.containsKey(model))
			{
				(this.models.getValue(model) as Model).onRemove();
				this.models.remove(model);
			}
		}
		
		/**
		 * 添加上下文关联
		 * @param context 上下文关联实例
		 * @param model 指定添加模型类，需继承 Model 类
		 */
		public function addContext(context:IContext, model:Class=null):void
		{
			if (model == null)
			{
				for each (model in this.contexts.keys)
				{
					this.bind(model, context);
				}
			}
			else
			{
				this.bind(model, context);
			}
		}
		
		/**
		 * 移除上下文关联
		 * @param context 上下文关联实例
		 * @param model 指定添加模型类，需继承 Model 类
		 */
		public function removeContext(context:IContext, model:Class=null):void
		{
			if (model == null)
			{
				for each (model in this.contexts.keys)
				{
					this.unbind(model, context);
				}
			}
			else
			{
				this.unbind(model, context);
			}
		}
		
		/**
		 * 获取模型
		 * @param model 模型类，需继承 Model 类
		 * @return
		 */
		public function getModel(model:Class):Model
		{
			return this.models.getValue(model);
		}
		
		/**
		 * 获取上下文关联
		 * @param model 模型实例
		 * @return
		 */
		public function getContext(model:Model):IContext
		{
			var list:ArrayList = this.contexts.getValue(this.models.getKey(model));
			
			return (list == null || list.length <= 0) ? null : list.element(list.length - 1);
		}
		
		/**
		 * 清除模型实例
		 */
		public function clear():void
		{
			var model:Class;
			
			for each (model in this.models.keys)
			{
				if (!this.contexts.containsKey(model) || !(this.contexts.getValue(model) is ArrayList) || (this.contexts.getValue(model) as ArrayList).length <= 0)
				{
					this.remove(model);
				}
			}
			
			for each (model in this.contexts.keys)
			{
				if (!this.models.containsKey(model) || !(this.models.getValue(model) is Model))
				{
					this.contexts.remove(model);
				}
			}
		}
		
		// -------------------------------------------------------------------------------------------------------- 函数
		
		/**
		 * 初始化
		 */
		private function init():void
		{
			this.models = new HashMap();
			this.contexts = new HashMap();
		}
		
		/**
		 * 给指定模型类绑定上下文关联
		 * @param model 指定添加模型类，需继承 Model 类
		 * @param context 上下文关联实例
		 */
		private function bind(model:Class, context:IContext):void
		{
			if (!this.contexts.containsKey(model))
			{
				this.contexts.put(model, new ArrayList());
			}
			
			var list:ArrayList = this.contexts.getValue(model) as ArrayList;
			list.add(context);
			
			if (!this.models.containsKey(model) || !this.contexts.containsKey(model))
			{
				this.add(model);
			}
		}
		
		/**
		 * 解除绑定指定模型类的上下文关联
		 * @param model 指定添加模型类，需继承 Model 类
		 * @param context 上下文关联实例
		 */
		private function unbind(model:Class, context:IContext):void
		{
			if (!this.contexts.containsKey(model))
			{
				return;
			}
			
			var list:ArrayList = this.contexts.getValue(model) as ArrayList;
			
			if (list.contains(context))
			{
				list.remove(context);
			}
			
			if (list.length <= 0)
			{
				this.contexts.remove(model);
			}
		}
	
	}
}
